<template>
  <div class="lm-container">
    <!-- 删除时触发的对话框 -->
    <div>
      <!-- 删除链接 -->
      <Modal v-model="dilLog_del_ari" width="360">
        <template #header>
          <p style="color: #f60; text-align: center">
            <Icon type="ios-information-circle"></Icon>
            <span>是否确定删除该链接!</span>
          </p>
        </template>

        <div style="text-align: center">
          <p>请选择操作</p>
        </div>
        <template #footer>
          <div>
            <Button @click="dilLog_del_ari = false">取消</Button>
            <Button type="error" @click="fun_dilLog_del_ari">确认删除</Button>
          </div>
        </template>
      </Modal>
      <!-- 删除子节点 -->
      <Modal v-model="dilLog_del_ari_rec_chi" width="360">
        <template #header>
          <p style="color: #f60; text-align: center">
            <Icon type="ios-information-circle"></Icon>
            <span>是否确定删除该文件夹!</span>
          </p>
        </template>

        <div style="text-align: center">
          <p>请选择操作</p>
        </div>
        <template #footer>
          <div>
            <Button @click="dilLog_del_ari_rec_chi = false">取消</Button>
            <Button type="error" @click="fun_dilLog_del_ari_rec_chi"
              >确认删除</Button
            >
          </div>
        </template>
      </Modal>
      <!-- 删除根节点 -->
      <Modal v-model="dilLog_del_ari_rec_root" width="360">
        <template #header>
          <p style="color: #f60; text-align: center">
            <Icon type="ios-information-circle"></Icon>
            <span>是否确定删除该文件夹!</span>
          </p>
        </template>

        <div style="text-align: center">
          <p>请选择操作</p>
        </div>
        <template #footer>
          <div>
            <Button @click="dilLog_del_ari_rec_root = false">取消</Button>
            <Button type="error" @click="fun_dilLog_del_ari_rec_root"
              >确认删除</Button
            >
          </div>
        </template>
      </Modal>
    </div>
    <!-- 控制面板 -->
    <Collapse
      class="padding"
      style="width: 100%; height: 100%; background: #fff !important"
    >
      <Panel name="1">
        管理链接
        <template #content>
          <!-- 左侧目录树 -->
          <div>
            <Input
              v-model="rootName"
              placeholder="请输入节点名字"
              clearable
              style="width: auto"
              @on-enter="addroot"
            />
            <Button type="primary" @click="addroot">添加根节点</Button>
            <Tree
              :data="data5"
              :render="renderContent"
              class="demo-tree-render"
              @on-contextmenu="handleContextMenu"
              expand-node
              @on-toggle-expand="get_showLint"
              ><template #contextMenu>
                <DropdownItem v-on:click="handleContextMenuAddLink"
                  >添加链接</DropdownItem
                >
                <DropdownItem v-on:click="paste_node(contextData)"
                  >粘贴到此</DropdownItem
                >
                <DropdownItem
                  v-on:click="copy_node(null, null, contextData, 'move', true)"
                  >移动</DropdownItem
                >
                <DropdownItem
                  v-on:click="copy_node(null, null, contextData, 'copy', true)"
                  >复制</DropdownItem
                >
                <DropdownItem v-on:click="append">新建文件夹</DropdownItem>
                <DropdownItem v-on:click="handleContextMenuEdit"
                  >重命名</DropdownItem
                >
                <DropdownItem
                  v-on:click="handleContextMenuDelete"
                  style="color: #ed4014"
                  >删除</DropdownItem
                >
              </template></Tree
            >
          </div>
        </template>
      </Panel>
      <Panel name="2">
        编辑链接
        <template #content>
          <!-- 右侧链接展示区 -->
          <div>
            <!-- 链接编辑器 -->
            <Editlink
              :transmit_model="show_Editlink"
              @ev_formData="deal_formData"
            ></Editlink>
            <!-- 链接管理 -->
            <List>
              <ListItem v-for="(item, i) in showLink" :key="i">
                <ListItemMeta
                  :avatar="item.link.linkLogo"
                  :title="item.link.linkName"
                  :description="item.link.describe"
                />
                <template #action>
                  <li>
                    <a href="#" @click="ev_editLink(item)">编辑</a>
                  </li>
                  <li>
                    <a :href="item.link.linkSite" target="_blank">查看</a>
                  </li>
                </template>
              </ListItem>
            </List>
          </div>
        </template>
      </Panel>
    </Collapse>
  </div>
</template>

<script>
import { resolveComponent } from 'vue'
import putBuffer from '@/api/API_Uploading_Directory_Tree'
import {
  PATH_Directory_tree_blogroll,
  nodeType_link,
  nodeType_root_node,
  nodeType_children_node
} from '@/mylibs/define'
import Editlink from './Editlink.vue'
import eventbus from '@/eventBus/eventbus'
import { renderContent } from '@/mylibs/node_render'
import { getUuid } from '@/mylibs/functions'
export default {
  emits: ['click'],
  components: { Editlink },
  data() {
    return {
      data5: [],
      // 右侧链接展示区的数据
      showLink: [],
      // 触发展示链接表单
      show_Editlink: 0,
      buttonProps: {
        type: 'default',
        size: 'small'
      },
      // 根节点右键触发 时 保存该节点
      contextData: null,
      rootName: '',
      remove_data: null,
      // oss删除链接--对话框
      dilLog_del_ari: false,
      // 递归删除文件夹(子)中的链接--对话框
      dilLog_del_ari_rec_chi: false,
      // 递归删除文件夹(根)中的链接--对话框
      dilLog_del_ari_rec_root: false,
      // 剪切,复制的节点
      copy_data: {
        root: null,
        node: null,
        data: null,
        // move copy
        type: '',
        is_root_data: false
      },
      // 根节点render函数
      root_render: (h, { root, node, data }) => {
        return h(
          'span',
          {
            style: {
              display: 'inline-block',
              width: '100%'
            }
          },
          [
            h('span', [
              h(resolveComponent('Icon'), {
                type: 'ios-folder-outline',
                style: {
                  marginRight: '8px'
                }
              }),
              h('span', data.title)
            ]),
            h(
              'span',
              {
                style: {
                  display: 'inline-block',
                  float: 'right',
                  marginRight: '8px'
                }
              },
              [
                h(resolveComponent('Button'), {
                  // vue3
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-up',
                  title: '上移',

                  style: {
                    width: '64px',
                    marginRight: '8px'
                  },
                  // vue3
                  onClick: (e) => {
                    this.rearrange(data, this.data5, -1, e)
                  }
                }),
                // vue3
                h(resolveComponent('Button'), {
                  // vue3
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-down',
                  title: '下移',

                  style: {
                    width: '64px',
                    marginRight: '0px'
                  },
                  // vue3
                  onClick: (e) => {
                    this.rearrange(data, this.data5, 1, e)
                  }
                })
              ]
            )
          ]
        )
      },
      // 链接节点render函数
      link_render: (h, { root, node, data }) => {
        return h(
          'span',
          {
            style: {
              display: 'inline-block',
              width: '100%'
            }
          },
          [
            h('span', [
              h(resolveComponent('Icon'), {
                type: 'ios-link-outline',
                style: {
                  marginRight: '8px'
                }
              }),
              h('span', data.title)
            ]),
            h(
              'span',
              {
                style: {
                  display: 'inline-block',
                  float: 'right',
                  marginRight: '0'
                }
              },
              [
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-up',
                  title: '上移',
                  style: {
                    marginRight: '8px'
                  },
                  onClick: (e) => {
                    this.rearrange(data, this.data5, -1, e)
                  }
                }),
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-down',
                  title: '下移',
                  style: {
                    marginRight: '8px'
                  },
                  onClick: (e) => {
                    this.rearrange(data, this.data5, 1, e)
                  }
                }),
                // 复制,移动按钮
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-move',
                  style: { marginRight: '8px' },
                  title: '移动',
                  onClick: (e) => {
                    this.copy_node(root, node, data, 'move', false, e)
                  }
                }),
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'md-copy',
                  title: '复制',
                  style: { marginRight: '8px' },
                  onClick: (e) => {
                    this.copy_node(root, node, data, 'copy', false, e)
                  }
                }),
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-remove',
                  style: {
                    marginRight: '8px'
                  },
                  onClick: (e) => {
                    this.delete_Oss_Article(root, node, data, e)
                  }
                })
              ]
            )
          ]
        )
      },
      // 后备内容渲染,节点没有 render函数则用该函数
      renderContent,
      children_render: (h, { root, node, data }) => {
        return h(
          'span',
          {
            style: {
              display: 'inline-block',
              width: '100%'
            }
          },
          [
            h('span', [
              h(resolveComponent('Icon'), {
                type: 'md-folder',
                style: {
                  marginRight: '8px'
                }
              }),
              h('span', data.title)
            ]),
            h(
              'span',
              {
                style: {
                  display: 'inline-block',
                  float: 'right',
                  marginRight: '0'
                }
              },
              [
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-up',
                  title: '上移',
                  style: {
                    marginRight: '8px'
                  },
                  onClick: (e) => {
                    this.rearrange(data, this.data5, -1, e)
                  }
                }),
                h(resolveComponent('Button'), {
                  ...this.buttonProps,
                  icon: 'ios-arrow-round-down',
                  title: '下移',
                  style: {
                    marginRight: '8px'
                  },
                  onClick: (e) => {
                    this.rearrange(data, this.data5, 1, e)
                  }
                })
              ]
            )
          ]
        )
      }
    }
  },
  // 监听器
  watch: {
    // 只要目录树数据变化了,就保存
    data5: {
      handler() {},
      deep: true
    }
  },
  // vue方法
  methods: {
    // 消息提示
    info(desc) {
      this.$Notice.info({
        title: '注意!',
        desc
      })
    },

    //递归目录树数据,设置根链接节点样式
    Recursive_directory_tree(dirData) {
      for (let index = 0; index < dirData.length; index++) {
        const element = dirData[index]
        if (element.node_type && element.node_type == nodeType_link) {
          element['render'] = this.link_render
        }
        if (element.node_type && element.node_type == nodeType_root_node) {
          element['render'] = this.root_render
        }

        if (element.node_type && element.node_type == nodeType_children_node) {
          element['render'] = this.children_render
        }
        if (element.children && element.children.length != 0) {
          // 子文件夹
          this.Recursive_directory_tree(element.children)
        }
      }
    },

    // 删除链接
    delete_Oss_Article(root, node, data, e) {
      e.stopPropagation()
      this.remove_data = {
        root,
        node,
        data
      }
      this.dilLog_del_ari = true
    },

    // 对话框确认删除
    fun_dilLog_del_ari() {
      this.dilLog_del_ari = false
      var data = this.remove_data.data,
        node = this.remove_data.node,
        root = this.remove_data.root
      // 从目录树中删除
      const parentKey = root.find((el) => el === node).parent
      const parent = root.find((el) => el.nodeKey === parentKey).node
      const index = parent.children.indexOf(data)
      parent.children.splice(index, 1)

      this.saveDataDir()
    },

    // 删除子节点
    remove(root, node, data, e) {
      e.stopPropagation()
      this.remove_data = {
        root,
        node,
        data
      }
      this.dilLog_del_ari_rec_chi = true
    },
    // 对话框确认删除
    fun_dilLog_del_ari_rec_chi() {
      this.dilLog_del_ari_rec_chi = false
      // 目录树
      const parentKey = root.find((el) => el === node).parent
      const parent = root.find((el) => el.nodeKey === parentKey).node
      const index = parent.children.indexOf(data)
      parent.children.splice(index, 1)
      this.saveDataDir()
    },

    // 添加根节点
    addroot() {
      // 判断输入是否为空
      var name = this.rootName
      if (name.length == 0) {
        this.info('节点名字为空!')
        return
      }

      this.data5.push({
        title: name,
        mynodeKey: getUuid(),
        // 开启右击
        contextmenu: true,
        expand: true,
        render: this.root_render,
        node_type: nodeType_root_node,
        children: []
      })

      this.saveDataDir()
    },

    // 右击处理函数
    handleContextMenu(data, event, position) {
      // 引用
      this.contextData = data
    },
    // 添加子节点(子文件夹)
    append() {
      var name = this.rootName
      if (name.length == 0) {
        this.info('节点名字为空!')
        return
      }
      var children = this.contextData.children || []
      children.push({
        title: name,
        mynodeKey: getUuid(),
        expand: true,
        render: this.children_render,
        // 添加了一个属性表示它是子文件夹,支持右键菜单
        contextmenu: true,
        node_type: nodeType_children_node,
        children: []
      })
      this.contextData.children = children
      this.saveDataDir()
    },

    // 重命名根节点,子节点
    handleContextMenuEdit() {
      var name = this.rootName
      if (name.length == 0) {
        this.info('节点名字为空!')
        return
      }
      this.contextData.title = name
      this.saveDataDir()
    },

    // 从目录树中删除子节点
    del_children_node(dirData, node) {
      for (let index = 0; index < dirData.length; index++) {
        const element = dirData[index]
        if (element.children && element.children.length != 0) {
          element.children = element.children.filter((item) => item != node)
          this.del_children_node(element.children, node)
        }
      }
    },

    // 删除根节点,子节点
    handleContextMenuDelete() {
      this.dilLog_del_ari_rec_root = true
    },
    // 对话框确认删除
    fun_dilLog_del_ari_rec_root() {
      this.dilLog_del_ari_rec_root = false

      // 从目录树中移除
      // 判断是根节点还是子节点
      // if (this.contextData.node_type == nodeType_children_node) {
      //   this.del_children_node(this.data5, this.contextData)
      //   this.saveDataDir()
      // } else {
      //   this.data5 = this.data5.filter(
      //     (item) => item.mynodeKey != this.contextData.mynodeKey
      //   )
      //   this.saveDataDir()
      // }
      this.del_from_datatree(this.contextData, this.data5)
      this.saveDataDir()
    },

    // 根节点,子节点 添加链接
    handleContextMenuAddLink() {
      // 展示表单
      this.show_Editlink++
    },

    // 处理传递的链接表单信息
    deal_formData(form) {
      console.log(form)
      var children = this.contextData.children || []
      children.push({
        title: form.linkName,
        mynodeKey: getUuid(),
        node_type: nodeType_link,
        render: this.link_render,
        link: form
      })
      this.contextData.children = children
      this.saveDataDir()
    },

    // 编辑链接
    ev_editLink(linkNode) {
      this.show_Editlink++
      eventbus.emit('need_editLink', linkNode)
    },

    // 获取目录树数据
    getDirTreeData() {
      putBuffer('get', PATH_Directory_tree_blogroll).then(
        ({ res, ok, err }) => {
          if (ok) {
            if (res) {
              if (Array.isArray(res)) {
                this.data5 = res
                // 节点样式
                this.Recursive_directory_tree(this.data5)
              } else {
                this.$Notice.info('数据非数组')
              }
            }
          } else {
            this.$Notice.error({ desc: '获取目录树数据失败:' + err })
          }
        }
      )
    },

    // 获取展示区数据
    get_showLint(node, isRec) {
      if (!isRec) {
        this.showLink.splice(0, this.showLink.length)
      }
      for (let index = 0; index < node.children.length; index++) {
        const element = node.children[index]
        if (element.node_type && element.node_type == nodeType_link) {
          this.showLink.push(element)
        }

        // 递归子文件夹
        // if (element.children && element.children.length != 0) {
        //   this.get_showLint(element, true)
        // }
      }
    },

    // 提交数据到阿里云oss
    saveDataDir() {
      putBuffer('put', PATH_Directory_tree_blogroll, this.data5).then(
        ({ ok }) => {
          if (!ok) {
            this.$Notice.error({ desc: '保存目录树数据失败:' + err })
          }
        }
      )
    },
    // 复制,移动
    copy_node(root, node, data, type, is_root, e) {
      if (e) {
        e.stopPropagation()
      }
      this.copy_data.node = node
      this.copy_data.type = type
      this.copy_data.data = data
      this.copy_data.root = root
      this.copy_data.is_root_data = is_root
      if (type == 'move') {
        this.$Notice.success({ desc: '已经剪切好了' })
      }
      if (type == 'copy') {
        this.$Notice.success({ desc: '已经复制好了' })
      }
    },

    is_copy_to_son(father_node, node) {
      var bo = false
      if (father_node.mynodeKey == node.mynodeKey) return true
      try {
        for (var index = 0; index < node.children.length; index++) {
          var element = node.children[index]
          if (element.node_type == nodeType_children_node) {
            if (element.mynodeKey == father_node.mynodeKey) {
              bo = true
              break
            }

            var bo1 = this.is_copy_to_son(father_node, element)
            if (bo1) {
              bo = true
              break
            }
          }
        }
      } catch (e) {
        console.log(e)
      }
      return bo
    },

    // 文件夹改变mynodeKey
    change_mynodeKey(node) {
      node.mynodeKey = getUuid()
      // 文件夹下的文章,文档的father_nodeKey也要改变
      if (
        node.node_type == nodeType_children_node ||
        node.node_type == nodeType_root_node
      ) {
        for (let index = 0; index < node.children.length; index++) {
          const element = node.children[index]
          if (element.node_type == nodeType_link) {
            element.father_nodeKey = node.mynodeKey
          }

          if (
            element.node_type == nodeType_children_node ||
            node.node_type == nodeType_root_node
          ) {
            this.change_mynodeKey(element)
          }
        }
      }
    },

    // 从datatree中删除某个元素
    del_from_datatree(node, array) {
      for (let index = 0; index < array.length; index++) {
        var element = array[index]
        if (node.mynodeKey == element.mynodeKey) {
          array.splice(array.indexOf(node), 1)
        }
        if (
          element.node_type == nodeType_children_node ||
          element.node_type == nodeType_root_node
        ) {
          this.del_from_datatree(node, element.children)
        }
      }
    },

    // 粘贴
    paste_node(father_node, e) {
      if (e) {
        e.stopPropagation()
      }
      if (!this.copy_data || !this.copy_data.data) {
        this.$Notice.info({ desc: '请先复制剪切 文件或者文件夹' })
        return
      }

      if (this.is_copy_to_son(father_node, this.copy_data.data)) {
        this.$Notice.info({ desc: '不能复制移动到它的子节点' })
        return
      }

      // 深拷贝对象
      var str = JSON.stringify(this.copy_data.data)
      var obj = JSON.parse(str)
      if (obj.node_type == nodeType_root_node) {
        obj.node_type = nodeType_children_node
      }
      console.log(obj)
      try {
        if (this.copy_data.type == 'copy') {
          // 改变mynodeKey
          if (obj.node_type == nodeType_link) {
            obj.mynodeKey = getUuid()
            obj.father_nodeKey = father_node.mynodeKey
          }
          if (
            obj.node_type == nodeType_children_node ||
            obj.node_type == nodeType_root_node
          ) {
            this.change_mynodeKey(obj)
          }

          father_node.children.push(obj)
          this.$Notice.success({ desc: '复制成功' })
          // 保存目录树到oss
          this.saveDataDir()
          this.Recursive_directory_tree(this.data5)
          // this.copy_data.data = null
        }
      } catch (e) {
        this.$Notice.error({ desc: '复制失败:' + e })
      }

      try {
        if (this.copy_data.type == 'move') {
          var bo_ok = true
          // 删除
          try {
            this.del_from_datatree(this.copy_data.data, this.data5)
          } catch (e) {
            this.$Notice.error({ desc: '移动失败--删除失败:' + e })
            console.log(e)
            var bo_ok = false
          }

          if (bo_ok) {
            // 移动  不需要改变mynodeKey
            // 添加
            father_node.children.push(obj)
            this.$Notice.success({ desc: '移动成功' })
            this.copy_data.data = null
            // 保存目录树到oss
            this.saveDataDir()
            this.Recursive_directory_tree(this.data5)
          }
        }
      } catch (e) {
        this.$Notice.error({ desc: '移动失败--添加失败:' + e })
        console.log(e)
      }
    },

    // 调整节点顺序
    rearrange(node, array, addPosNum, e) {
      if (e) {
        e.stopPropagation()
      }
      for (let index = 0; index < array.length; index++) {
        const element = array[index]
        if (element.mynodeKey == node.mynodeKey) {
          let pos = array.indexOf(node)
          if (pos + addPosNum < 0 || pos + addPosNum > array.length - 1) {
            this.$Notice.info({ desc: '超出了范围' })
          } else {
            // 删除
            array.splice(pos, 1)
            // 添加
            pos += addPosNum
            array.splice(pos, 0, node)
            // 保存目录树到oss
          this.saveDataDir()
          }

          return 0
        }

        if (
          element.node_type == nodeType_children_node ||
          element.node_type == nodeType_root_node
        ) {
          let res = this.rearrange(node, element.children, addPosNum)
          if (res == 0) {
            return 0
          }
        }
      }
    }
  },
  //生命周期函数
  created() {},
  // 激活该路由组件时调用
  activated() {
    // 链接组件 激活
    this.getDirTreeData()
  },
  deactivated() {
    // 链接组件 缓存
  }
}
</script>
<style scoped>
.lm-container {
  display: flex;
}
.margin {
  margin: 10px 10px;
}

.padding {
  padding: 10px 10px;
}
</style>
